package com.shu.rpc.rpc1.server;

import com.shu.rpc.rpc1.common.service.ProductService;
import com.shu.rpc.rpc1.server.impl.ProductServiceImpl;
import lombok.extern.slf4j.Slf4j;

import java.io.InputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.lang.reflect.Method;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.Objects;

/**
 * @author ssm
 * @version V1.0
 * @description:
 * @date 2020/6/12 9:54
 */
@Slf4j
public class ServerDemo {

    /**
     * 服务端
     *
     * @param args
     */
    public static void main(String[] args) throws Exception {
        try {
            // 发布服务 Socket 端口
            ServerSocket serverSocket = new ServerSocket(8888);

            //2.监听端口
            while (true) {
                log.info("服务端启动成功,监听中-----");
                Socket socket = serverSocket.accept();
                log.info("服务端调用开始");

                // 使用socket接收参数[接口,方法,参数],-> 然后用反射invoke 再返回值
                InputStream is = socket.getInputStream();
                ObjectInputStream obis = new ObjectInputStream(is);
                String clzName = obis.readUTF();
                String methodName = obis.readUTF();
                Class[] parameterTypes = (Class[]) obis.readObject();
                Object[] arg = (Object[]) obis.readObject();
                log.info("{}#{}#{}",clzName,methodName,arg);

                // 服务注册，找到具体的实现类
                Class clz = null;
                if (Objects.equals(ProductService.class.getName(), clzName)) {
                    clz = ProductServiceImpl.class;
                }

                // 使用反射调用方法
                Method method = clz.getMethod(methodName, parameterTypes);

                Object result = method.invoke(clz.newInstance(), arg);

                // 返回对象给调用这
                ObjectOutputStream oos = new ObjectOutputStream(socket.getOutputStream());
                oos.writeObject(result);
                oos.flush();
                log.info("服务端调用结束");
            }
        } catch (Exception e) {
            e.printStackTrace();
        }

    }
}
